/************************************************************************
  * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
  * @file     tp_ctp.c
  * @author   UartTFT Application Team
  * @version  V0.0.1
  * @date     2023-01-01
  * @brief    
 *************************************************************************/

#include "tp_ctp.h"
#include "tp_iic.h"
#include "function_drv.h"

//#include "i2c_drv.h"
//#include "eport_drv.h"
//#include "spi_drv.h"

uint8_t ctp_press_t;

#if (LT_TOUCH_FLAG == 2)

uint8_t READ_BUFF[128];
uint8_t WRITE_BUFF[20];
uint8_t ctp_active_index = 0;

uint8_t gt911flag = 0;
uint8_t cjt540flag = 0;
uint8_t ft5216flag = 0;
uint8_t CST816Dflag = 0;
uint8_t chsc5xxxflag = 0;
uint8_t CTP_ADDR = 0;
uint16_t X_Output_Max, Y_Output_Max;
uint16_t X_Output_Size, Y_Output_Size;

uint8_t CTP_ConfigureBuff[186] =
	{
		0x41, 0x00, 0x04, 0x58, 0x02, 0x0A, 0x0D, 0x00, 0x01, 0xC8,
		0x28, 0x0F, 0x50, 0x32, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x29, 0x77,
		0x17, 0x15, 0x31, 0x0D, 0x00, 0x00, 0x00, 0x9A, 0x03, 0x2D,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x0F, 0x37, 0x94, 0xC5, 0x02, 0x08, 0x00, 0x00, 0x00,
		0x9B, 0x11, 0x00, 0x7A, 0x16, 0x00, 0x62, 0x1C, 0x00, 0x4C,
		0x25, 0x00, 0x3D, 0x30, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
		0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x02, 0x04, 0x06, 0x07, 0x08, 0x0A, 0x0C,
		0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x19, 0x1B,
		0x1C, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0xA4, 0x01};

void Checksum(uint8_t *p) // Configuration information check 0x80ff (checked algorithm is correct)
{
	int32_t i = 0;
	uint32_t sum_buffer = 0;

	for (; i < 184; i++)
	{
		sum_buffer += *(p + i);
	}

	*(p + 184) = ~sum_buffer + 1;
//	printf("%x\r\n", *(p + 184));
}

//---------------------------------clear buffer-------------------------//
void ClearBuff(uint8_t *p)
{
	int32_t i = 0;
	for (; i < 20; i++)
	{
		*(p + i) = 0;
	}
}

/*************Get the interrupt pin level*************/


/******************************************************************************
 * DESCRIPTION: Write touch screen register
 ******************************************************************************/
uint8_t CTP_BufferWrite(uint8_t *pBuffer, uint32_t WriteAddr, uint8_t AddrByte, uint16_t NumByte)
{
	uint32_t addr;

	CTI2C_Start();

	CTI2C_write_byte((CTP_ADDR) | 0);
	for (; AddrByte > 0; AddrByte--)
	{
		addr = WriteAddr;
		for (uint8_t i = 1; i < AddrByte; i++)
			addr >>= 8;
		CTI2C_write_byte(addr & 0xFF);
	}

	while (NumByte--)
	{
		CTI2C_write_byte(*pBuffer);
		pBuffer++;
	}

	CTI2C_Stop();

	return 0;
}

/******************************************************************************
 * DESCRIPTION: Read data from the touch screen
 ******************************************************************************/
uint8_t CTP_BufferRead(uint8_t *pBuffer, uint32_t ReadAddr, uint8_t AddrByte, uint16_t NumByte)
{
	uint32_t addr;

	CTI2C_Start();
	CTI2C_write_byte(CTP_ADDR | 0);
	for (; AddrByte > 0; AddrByte--)
	{
		addr = ReadAddr;
		for (uint8_t i = 1; i < AddrByte; i++)
			addr >>= 8;
		CTI2C_write_byte(addr & 0xFF);
	}
	CTI2C_Stop();

	CTI2C_Start();
	CTI2C_write_byte(CTP_ADDR | 0x01);
	for (; NumByte > 1; NumByte--)
	{
		*pBuffer = CTI2C_read_byte(0);
		pBuffer++;
	}
	*pBuffer = CTI2C_read_byte(1);

	CTI2C_Stop();

	return 0;
}

// 读坐标
uint8_t TP_read_XY(void)
{
	uint16_t x, y;
	uint8_t temp = 0;

	if (cjt540flag)
	{

		READ_BUFF[0] = 0;
		CTP_BufferRead(READ_BUFF, 0xD000, 2, 7);
		temp = READ_BUFF[0];
		// printf("temp = 0x%x \r\n",temp);
		if (((temp & 0x0F) >> 1) == 0x03) // buffer status == 1, data valid
		{
			x = (READ_BUFF[1] << 4) | ((READ_BUFF[3] >> 4) & 0x0F);
			y = (READ_BUFF[2] << 4) | (READ_BUFF[3] & 0x0F);

			gTpInfo.x[0] = x;
			gTpInfo.y[0] = y;

			gTpInfo.sta = 1;
			if (gTpInfo.x[0] > LCD_XSIZE_TFT)	gTpInfo.x[0] = LCD_XSIZE_TFT;
			if (gTpInfo.y[0] > LCD_YSIZE_TFT)	gTpInfo.y[0] = LCD_YSIZE_TFT;
				

			if (First_press == 0)
			{
				First_press = 1;
				First_pressX = gTpInfo.x[0];
				First_pressY = gTpInfo.y[0];
			}
			// printf("x=%d y=%d\r\n",x,y);
			// printf("gTpInfo.x=%d gTpInfo.y=%d\r\n",gTpInfo.x[0],gTpInfo.y[0]);

			READ_BUFF[0] = 0xAB;
			CTP_BufferWrite(READ_BUFF, 0xD000, 2, 1);
		}
		else
		{
			gTpInfo.sta = 0;
			First_press = 0;
		}
	}
	else if (gt911flag)
	{
		CTP_BufferRead(READ_BUFF, 0x814E, 2, 1);
		temp = READ_BUFF[0] & 0x8F;
		// printf("temp = 0x%x  \r\n",temp);
		if (temp & 0x80) // buffer status ==1 && number of touch points > 0
		{
			CTP_BufferRead(READ_BUFF, 0x814F, 2, 5 * 8); // read
			READ_BUFF[0] = 0;
			CTP_BufferWrite(READ_BUFF, 0x814E, 2, 1); // clear
		}

		if((temp&0x8F)==0x81)
		{
			x = ((READ_BUFF[2] & 0x0F) << 8) | READ_BUFF[1];
			y = ((READ_BUFF[4] & 0x0F) << 8) | READ_BUFF[3];

			gTpInfo.x[0] = x * X_Output_Size / X_Output_Max;
			gTpInfo.y[0] = y * Y_Output_Size / Y_Output_Max;
			// printf("x=%d y=%d\r\n",gTpInfo.x[0],gTpInfo.y[0]);

			if (gTpInfo.x[0] > LCD_XSIZE_TFT)	gTpInfo.x[0] = LCD_XSIZE_TFT;
			if (gTpInfo.y[0] > LCD_YSIZE_TFT)	gTpInfo.y[0] = LCD_YSIZE_TFT;
				


			if (First_press == 0)
			{
				First_press = 1;
				First_pressX = gTpInfo.x[0];
				First_pressY = gTpInfo.y[0];
			}
			//LTPrintf(" x=%d y=%d \r\n",gTpInfo.x[0],gTpInfo.y[0]);

			gTpInfo.sta = 1;
		}

		if((temp&0x8F)==0x80)
		{
			//if(gTpInfo.sta)
			gTpInfo.sta = 0;
			First_press = 0;
		}
	}
	else if (ft5216flag || CST816Dflag)
	{

		CTP_BufferRead(READ_BUFF, 0x02, 1, 1); // Number of touch points
		if (READ_BUFF[0] > 0)
		{
			CTP_BufferRead(READ_BUFF, 0x03, 1, 5 * 6);
			temp = READ_BUFF[0] >> 6; // bits 00: press down  01:raise  10:keep press   11:No event
		}
		else
			temp = 3;


		if (temp == 0 || temp == 2)
		{
			x = ((READ_BUFF[0] & 0x0F) << 8) | READ_BUFF[1];
			y = ((READ_BUFF[2] & 0x0F) << 8) | READ_BUFF[3];
			gTpInfo.x[0] = x;
			gTpInfo.y[0] = y;

			if (gTpInfo.x[0] > LCD_XSIZE_TFT)	gTpInfo.x[0] = LCD_XSIZE_TFT;
			if (gTpInfo.y[0] > LCD_YSIZE_TFT)	gTpInfo.y[0] = LCD_YSIZE_TFT;
				

			if (First_press == 0)
			{
				First_press = 1;
				First_pressX = gTpInfo.x[0];
				First_pressY = gTpInfo.y[0];
			}
			//LTPrintf("x=%d y=%d   \r\n",gTpInfo.x[0],gTpInfo.y[0]);
			gTpInfo.sta = 1;
		}
		else if (temp == 3 || temp == 1)
		{
			gTpInfo.sta = 0;
			First_press = 0;
		}
	}
	else if (chsc5xxxflag)
	{

		CTP_BufferRead(READ_BUFF, 0x00, 1, 15); //

		temp = READ_BUFF[3] >> 4; // bits 0X00:press down     0X08:keep press   0X04:raise

		if (temp == 0 || temp == 0x08)
		{
			x = ((READ_BUFF[3] & 0x0F) << 8) | READ_BUFF[4];
			y = ((READ_BUFF[5] & 0x0F) << 8) | READ_BUFF[6];

			gTpInfo.x[0] = x;
			gTpInfo.y[0] = y;
//			printf("x=%d y=%d\r\n",gTpInfo.x[0],gTpInfo.y[0]);

			if (gTpInfo.x[0] > LCD_XSIZE_TFT)	gTpInfo.x[0] = LCD_XSIZE_TFT;
			if (gTpInfo.y[0] > LCD_YSIZE_TFT)	gTpInfo.y[0] = LCD_YSIZE_TFT;
				

			if (First_press == 0)
			{
				First_press = 1;
				First_pressX = gTpInfo.x[0];
				First_pressY = gTpInfo.y[0];
			}
			//printf("x=%d y=%d\r\n",gTpInfo.x[0],gTpInfo.y[0]);
			gTpInfo.sta = 1;
		}
		else if (temp == 0x04)
		{
			gTpInfo.sta = 0;
			First_press = 0;
			
		}
	}
}

uint8_t CTP_Scan(void)
{
	if (ctp_active_index == 1)
	{
		TP_read_XY();
		ctp_active_index = 0;
		return 1;
	}
	else
	{
		return 0;
	}
}
//void EPORT0_Handler(void)
//{
//	uint16_t h_test_temp;
//	h_test_temp = EPORT0->EPFR;
//	EPORT0->EPFR = h_test_temp;
//	ctp_active_index = 1;
//}
/*****************Initialization function of IO port related to capacitive touch screen************************/
void CTP_IO_Init(void)
{
	uint8_t ack, i;

	cjt540flag = 0;
	gt911flag = 0;
	ft5216flag = 0;

	// IO_Init
	// IOCTRL->I2C_CONTROL_REG |= 0x03;           //Enhance I2C drive capability


	OPTION->ADCCDISR = 0x0000;
	OPTION->ADCCDISR = 0x4000;
	OPTION->ADCCDISR = 0x8000;
	OPTION->ADCCDISR = 0xC000;
	OPTION->ADCCDISR = 0xC03F;//EPORT0[4~5]

	I2C->I2CC = 0x00;
	I2C->I2CPCR = 0xC3;	//Set SDA,SCL GPIO
	I2C->I2CDDR = 0x03;	//Set SDA,SCL output
	I2C->I2CPDR = 0x03;

	CTP_RST_OUTPUT;
	CTP_INT_OUTPUT;
	CTP_SCL_OUTPUT;
	CTP_SCL_PULLUP;
	CTP_SDA_OUTPUT;
	CTP_SDA_PULLUP;

	CTP_INT_LOW;
	CTP_RST_LOW;
	DelayMS(2);
	CTP_INT_HIGH;
	DelayMS(2);
	CTP_RST_HIGH;
	DelayMS(10);
	CTP_INT_LOW;
	DelayMS(60);
	CTP_INT_INPUT;
	DelayMS(20);

	EPORT0->EPDDR &= ~0x20;
	EPORT0->EPIER |= 0x20;
	EPORT0->EPPAR = 0x0800;
	EPORT1->EPFR = 0x20;
	EIC->IER |= IRQ(30);


//	I2C->I2CC = 0x00;
//	I2C->I2CPCR = 0xC3;	//Set SDA,SCL GPIO
//	I2C->I2CDDR = 0x03;	//Set SDA,SCL output
//	I2C->I2CPDR = 0x03;
//
//	CCM->U32_EPORT2FCR.EPORT2EN_6=1;
//	CCM->U32_EPORT2FCR.EPORT2EN_7=1;
//	EPORT2->EPDDR |= (1<<7)|(1<<6); 	//输出方向
//	EPORT2->EPPUE|= (3<<6);
//	EPORT2->EPDR |= (3<<6);
//
//	//INT04	RST
//	//INT05	INT
//	//解锁并且将ADC[7:0]切换为EPORT0[7:0]
//	OPTION->ADCCDISR = 0x0;
//	OPTION->ADCCDISR = 0x4000;
//	OPTION->ADCCDISR = 0x8000;
//	OPTION->ADCCDISR = 0xC000;
//	OPTION->ADCCDISR= 0xC030;
//
//	EPORT0->EPDDR |= (1<<4); 	//输出方向
//	EPORT0->EPPUE&=~ (1<<4);
//	EPORT0->EPDR |= (1<<4); 	//输出1
//	Delay_Ms(10);
//	EPORT0->EPDR &=~ (1<<4);
//	Delay_Ms(400);
//	EPORT0->EPDR |= (1<<4); 	//输出1
//	Delay_Ms(400);
//
//	EPORT0->EPDDR &=~ (1<<5);
//	EPORT0->EPPUE&=~ (1<<5);
//	EPORT0->EPPAR &=~ (3<<10);
//	EPORT0->EPPAR |=(2<<10);
//	EPORT0->EPLPR &=~ (1<<5);
	// slave addr scan
	//ft5216flag = 1;
	for (i = 0; i < 128; i++)
	{
		CTI2C_Start();
		ack = CTI2C_write_byte(i << 1);
		CTI2C_Stop();
		if (!ack)
		{
			CTP_ADDR = (i << 1);
			if (CTP_ADDR == 0x28)
			{
				gt911flag = 1;
				CTP_BufferRead(READ_BUFF, 0x8146, 2, 4);
				X_Output_Max = (READ_BUFF[1] << 8 | READ_BUFF[0]);
				Y_Output_Max = (READ_BUFF[3] << 8 | READ_BUFF[2]);
				X_Output_Size = LCD_XSIZE_TFT;
				Y_Output_Size = LCD_YSIZE_TFT;
			}
			else if (CTP_ADDR == 0x34)
				cjt540flag = 1;
			else if (CTP_ADDR == 0x70)
				ft5216flag = 1;
			else if (CTP_ADDR == 0x2a)
				CST816Dflag = 1; // CST816D
			// else if(CTP_ADDR==0xaa)	ST1663iflag	=	1;    //ST1663i
			else if (CTP_ADDR == 0x5C)
				chsc5xxxflag = 1;
			break;
		}
		DelayUS(1);
	}
//	LTPrintf("CTP_ADDR = 0x%x \r\n", CTP_ADDR);

}

void CTP_Init(void)
{
	CTP_IO_Init();
	gTpInfo.scan = CTP_Scan;
}

#endif




































